package org.devside.grails.mailqueue;

import org.apache.log4j.Logger;
import org.devside.grails.queue.MessageQueue;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.devside.common.utils.ExceptionUtils;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

/**
 * 邮件发送队列
 * User: matianyi
 * Date: 2010-6-2
 */
public class MailQueue extends MessageQueue<MailMessage> {

    private static final Logger LOG = Logger.getLogger(MailQueue.class);

    /**
     * 容量
     */
    public int queueBound = 100;

    /**
     * 失败尝试次数
     */
    private int retryTimes = 5;

    private JavaMailSender mailSender;

    private FailureMailService failureMailService;


    public JavaMailSender getMailSender() {
        return mailSender;
    }

    public void setMailSender(JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }

    public FailureMailService getFailureMailService() {
        return failureMailService;
    }

    public void setFailureMailService(FailureMailService failureMailService) {
        this.failureMailService = failureMailService;
    }

    @Override
    protected int getQueueBound() {
        return queueBound;
    }

    /**
     * 设定队列容量, 默认100
     *
     * @param queueBound 队列容量
     */
    public void setQueueBound(int queueBound) {
        this.queueBound = queueBound;
    }

    /**
     * 取得失败尝试次数
     *
     * @return 失败尝试次数
     */
    public int getRetryTimes() {
        return retryTimes;
    }

    /**
     * 设定失败尝试次数，默认5
     *
     * @param retryTimes 失败尝试次数
     */
    public void setRetryTimes(int retryTimes) {
        this.retryTimes = retryTimes;
    }

    @Override
    protected void consume(final MailMessage msg) {
        boolean failure = true;
        String error = null;
        for (int i = 0; i < getRetryTimes(); i++) {
            try {
                getMailSender().send(new MimeMessagePreparator() {
                    public void prepare(MimeMessage mimeMessage) throws MessagingException {
                        MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true, "UTF-8");
                        message.setTo(msg.getTo());
                        message.setReplyTo(msg.getReplyTo());
                        message.setText(msg.getBody());
                        message.setFrom(msg.getFrom());
                        message.setSubject(msg.getSubject());
                        if (msg.isMultipart()) {
                            message.addAttachment(msg.getFilename(), new ByteArrayResource(msg.getAttachBytes()), msg.getContentType());
                        }
                    }
                });
                failure = false;
                break;
            } catch (Exception e) {
                error = ExceptionUtils.getErrorStack(e);
            }
        }
        if (failure) {
            try {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("fail to send mail:" + msg.toString());
                }
                failureMailService.save(msg, error);
            } catch (Exception e) {
                LOG.error(e.getMessage(), e);
            }
        } else {
            if (LOG.isDebugEnabled()) {
                LOG.debug("success to send mail:" + msg.toString());
            }
        }
    }

}
